/*
 * Copyright (C) 2020 Baidu, Inc. All Rights Reserved.
 */
package cn.xiaoxige.plugin.transform

import org.objectweb.asm.AnnotationVisitor
import org.objectweb.asm.Attribute
import org.objectweb.asm.ClassVisitor
import org.objectweb.asm.FieldVisitor
import org.objectweb.asm.MethodVisitor
import org.objectweb.asm.ModuleVisitor
import org.objectweb.asm.Opcodes
import org.objectweb.asm.TypePath

class LifecycleClassVisitor extends ClassVisitor {

    private def mClassName

    public LifecycleClassVisitor(ClassVisitor cv) {
        super(Opcodes.ASM6, cv)
    }

    @Override
    void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
        super.visit(version, access, name, signature, superName, interfaces)
        println("visit -> $name, $signature, $superName")
        mClassName = name
    }

    @Override
    void visitSource(String source, String debug) {
        super.visitSource(source, debug)
        println("visitSource -> $source, $debug")
    }

    @Override
    ModuleVisitor visitModule(String name, int access, String version) {
        println("visitModule -> $name")
        return super.visitModule(name, access, version)
    }

    @Override
    void visitOuterClass(String owner, String name, String desc) {
        super.visitOuterClass(owner, name, desc)
        println("visitOuterClass -> $owner, $name")
    }

    @Override
    AnnotationVisitor visitAnnotation(String desc, boolean visible) {
        println("visitAnnotation -> $desc")
        return super.visitAnnotation(desc, visible)
    }

    @Override
    AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
        println("visitTypeAnnotation -> ${typePath.toString()}")
        return super.visitTypeAnnotation(typeRef, typePath, desc, visible)
    }

    @Override
    void visitAttribute(Attribute attr) {
        super.visitAttribute(attr)
        println('visitAttribute')
    }

    @Override
    void visitInnerClass(String name, String outerName, String innerName, int access) {
        super.visitInnerClass(name, outerName, innerName, access)
        println("visitInnerClass -> $name")
    }

    @Override
    FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
        println("visitField -> $name")
        return super.visitField(access, name, desc, signature, value)
    }

    @Override
    MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
        println("visitMethod -> $name")
        def mv = cv.visitMethod(access, name, desc, signature, exceptions)
        if (name == 'onCreate') {
            return new LifecycleMethodVisitor(mv, mClassName, name)
        }
        return mv
    }


    @Override
    void visitEnd() {
        super.visitEnd()
        println('visitEnd')
    }
}